package com.mapbased.cc.form;

import java.io.*;
import java.util.*;

import org.dom4j.*;
import com.mapbased.cc.*;
import com.mapbased.wfw.*;
import com.mapbased.wfw.PageLoader.*;

/**
 * <p>Title: </p>
 *
 * <p>Description: </p>
 *
 * <p>Copyright: Copyright (c) 2006</p>
 *
 * <p>Company: mapbased.com</p>
 *
 * @author chy_hs(Baily)
 * @version 1.0
 */
public class GroupFormElement
    extends FormElement
{

    static class GroupItem
    {
        String caption;
        String value;
        boolean isDefault;

    }

    public static final int GT_MULTIITEM=1;
    public static final int GT_RADIO=0;
    public static final int GT_SELECT=2;

    private int groupType=GT_RADIO;
    GroupItem[] _items=null;
    String extStr;
    Binding map;

    private GroupItem[] getItems(RenderContext r)
    {
        if(this.map == null)
        {
            return this._items;
        }
        else
        {
            Object o=this.map.getValue(r);
            if(!(o instanceof Map))
            {
                throw new java.lang.RuntimeException(
                    "Mapbing must return a Map");
            }
            Map m=(Map)o;
            //GroupItem [] c=new GroupItem[m.size()];
            java.util.List ll=new java.util.ArrayList(m.size());
            java.util.Iterator ii=m.entrySet().iterator();

            while(ii.hasNext())
            {
                Map.Entry me=(Map.Entry)ii.next();
                GroupItem gi=new GroupItem();
                gi.caption=String.valueOf(me.getValue());
                gi.value=String.valueOf(me.getKey());
                ll.add(gi);

            }
            return(GroupItem[])ll.toArray(new GroupItem[ll.size()]);
        }
    }

    /**
     * initCustom
     *
     * @param e Element
     * @param pl LoadContext
     * @todo Implement this com.mapbased.cc.form.FormElement method
     */
    protected void initCustom(Element e,LoadContext pl)
    {
        Element ele=e.element("groupelement");
        if(ele == null)
        {
            return;
        }

        String gt=ele.attributeValue("type");
        if(gt != null)
        {
            gt=gt.toLowerCase();
            if(gt.startsWith("select"))
            {
                this.groupType=GT_SELECT;
            }
            else if(gt.startsWith("multi"))
            {
                this.groupType=GT_MULTIITEM;
            }

        }
        java.util.List as=ele.attributes();
        StringBuffer sb=new StringBuffer(" ");
        for(int i=0;i < as.size();i++)
        {
            Attribute a=(Attribute)as.get(i);
            if(a.getName().equals("type"))
            {
                continue;
            }
            sb.append(a.getName()).append("=\"").append(a.getValue()).append(
                "\" ");
        }
        this.extStr=sb.toString();

        String enumclass=ele.attributeValue("valuelistclass","");
        if(enumclass != null && !enumclass.equals(""))
        {
            try
            {
                Class clz=Thread.currentThread().getContextClassLoader()
                    .loadClass(enumclass);
                ValueList vl=(ValueList)clz.newInstance();
                List vas=vl.getValues();

                this._items=new GroupItem[vas.size()];
                for(int i=0;i < vas.size();i++)
                {
                    GroupItem gi=new GroupItem();
                    gi.caption=((ValueList)vas.get(i)).getName();
                    gi.value=((ValueList)vas.get(i)).getCode();
                    this._items[i]=gi;
                }
                return;
            }
            catch(Exception ex)
            {
                System.err.println("Error while get listvalue from:" +
                                   enumclass + ex.toString());
                //return null;
            }
        }

        String mapbinding=ele.attributeValue("mapbinding","");
        if(mapbinding.length() > 0)
        {
            LoadContext nlc=new LoadContext(pl);
            List l=nlc.segments;
            pl.loader.parseBinding(mapbinding,nlc);
            try
            {
                this.map=(Binding)l.get(0);
            }
            catch(Exception ex1)
            {
                throw new java.lang.RuntimeException(
                    "Error getting map binding:"
                    + mapbinding);
            }

            return;
        }

        java.util.List l=ele.elements("groupitem");
        this._items=new GroupItem[l.size()];
        for(int i=0;i < this._items.length;i++)
        {
            GroupItem gi=new GroupItem();
            Element ge=(Element)l.get(i);

            gi.caption=ge.attributeValue("caption");
            if(gi.caption == null)
            {
                gi.caption="";
            }
            gi.isDefault="true".equals(ge.attributeValue("default"));
            gi.value=ge.attributeValue("value");
            if(gi.value == null)
            {
                gi.value="";
            }
            this._items[i]=gi;

        }

    }

    /**
     * renderInputPart
     *
     * @param rc RenderContext
     * @throws IOException
     * @todo Implement this com.mapbased.cc.form.FormElement method
     */
    public void renderInputPart(RenderContext rc)
        throws IOException
    {
        GroupItem[] items=this.getItems(rc);

        if(items == null)
        {
            return;
        }
        if(this.groupType == GT_RADIO)
        {
            this.renderRadio(rc,items);
        }
        else if(this.groupType == GT_MULTIITEM)
        {
            this.renderMulti(rc,items);
        }
        else
        {
            this.renderSelect(rc,items);
        }
    }

    private void renderRadio(RenderContext rc,GroupItem[] items)
        throws IOException
    {
        java.io.Writer w=rc.getOutputWriter();
        w.write("<div");
        if(this.css != null)
        {
            w.write(" class=\"");
            w.write(this.css);
            w.write("\" >");
        }

        String cs=rc.getSureSingleParam(this.name);
        if(cs.equals(""))
        {
            cs=null;
        }

        StringBuffer sb=new StringBuffer();
        for(int i=0;i < items.length;i++)
        {

            GroupItem gi=items[i];
            sb.append("<span><input type=\"radio\" name=\"");
            sb.append(this.name);
            sb.append("\" id=\"");
            sb.append(this.name);
            sb.append("_");
            sb.append(i);

            sb.append("\" value=\"");
            sb.append(gi.value);
            sb.append("\" ");
            if((cs != null && cs.equals(gi.value))
               || (cs == null && gi.isDefault))
            {
                sb.append("checked=\"checked\" ");

            }
            if(this.events != null)
            {
                sb.append(this.events);
            }

            sb.append(" /><label for=\"")
                .append(this.name)
                .append("_")
                .append(i)
                .append("\">")
                .append(gi.caption)
                .append("</label></span>");
            w.write(sb.toString());
            sb.setLength(0);

        }
        w.write("</div>");
    }

    private void renderSelect(RenderContext rc,GroupItem[] items)
        throws IOException
    {
        StringBuffer sb=new StringBuffer();
        java.io.Writer w=rc.getOutputWriter();
        sb.append("<select ")

            .append(this.events == null ? "" : this.events)
            .append(this.extStr)
            .append(" name=\"")
            .append(this.name)
            .append("\" id=\"")
            .append(this.name)
            .append("\" >");
        w.write(sb.toString());
        sb.setLength(0);
        String cs=rc.getSureSingleParam(this.name);
        if(cs.equals(""))
        {
            cs=null;
        }

        for(int i=0;i < items.length;i++)
        {
            GroupItem gi=items[i];
            sb.append("<option value=\"")
                .append(gi.value);
            if((cs != null && cs.equals(gi.value))
               || (cs == null && gi.isDefault))
            {
                sb.append("\" selected=\"selected");

            }

            sb.append("\" >")
                .append(gi.caption)
                .append("</option>");
            w.write(sb.toString());
            sb.setLength(0);
        }
        w.write("</select>");

    }

    private void renderMulti(RenderContext rc,GroupItem[] items)
        throws IOException
    {

    }

    public void setExtStr(String extStr)
    {
        this.extStr=extStr;
    }

    public void setGroupType(int groupType)
    {
        this.groupType=groupType;
    }

    public void setMapBinding(com.mapbased.wfw.Binding map)
    {
        this.map=map;
    }

    public void setGroupItems(com.mapbased.cc.form.GroupFormElement.GroupItem[]
                              _items)
    {
        this._items=_items;
    }

    public void setValueList(ValueList vl)
    {
        List vas=vl.getValues();

        this._items=new GroupItem[vas.size()];
        for(int i=0;i < vas.size();i++)
        {
            GroupItem gi=new GroupItem();
            gi.caption=((ValueList)vas.get(i)).getName();
            gi.value=((ValueList)vas.get(i)).getCode();
            this._items[i]=gi;
        }

    }

}
